package com.wll.design.观察者.controller;

import com.wll.design.观察者.eventbus.EventBusCenter;
import com.wll.design.观察者.eventbus.EventListener;
import com.wll.design.观察者.eventbus.NotifyEvent;
import com.wll.design.观察者.springboot.event.CustomEvent;
import com.wll.design.观察者.springboot.event.MessageEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName: GCTestController.java
 * @author: wanglulu
 * @version: 1.0.0
 * @Description: 观察者 设计模式
 * <p>
 * 4.2 观察者模式定义
 * 观察者模式定义对象间的一种一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都得到通知并被完成业务的更新。
 * <p>
 * 观察者模式属于行为模式，一个对象（被观察者）的状态发生改变，所有的依赖对象（观察者对象）都将得到通知，进行广播通知。它的主要成员就是观察者和被观察者。
 * <p>
 * 被观察者（Observerable）：目标对象，状态发生变化时，将通知所有的观察者。
 * 观察者（observer）：接受被观察者的状态变化通知，执行预先定义的业务。
 * 使用场景： 完成某件事情后，异步通知场景。如，登陆成功，发个IM消息等等。
 * <p>
 * 4.3 观察者模式使用
 * 观察者模式实现的话，还是比较简单的。
 * <p>
 * 一个被观察者的类Observerable ;
 * 多个观察者Observer ；
 * 观察者的差异化实现
 * 经典观察者模式封装：EventBus实战
 * 4.3.1 一个被观察者的类Observerable 和 多个观察者Observer
 * @createTime: 2021/11/25 15:20
 */
@RestController
@RequestMapping("/push/")
@Slf4j
public class GCTestController {


    /**
     * 基于 Guava EventBus 实现
     * @param args
     */
    public static void main(String[] args) {
        EventListener eventListener = new EventListener();
        EventBusCenter.register(eventListener);
        EventBusCenter.post(new NotifyEvent("13372817283", "123@qq.com", "666"));
    }


    /**
     * 注入 事件发布类
     */
    @Autowired
    ApplicationEventPublisher eventPublisher;

    @GetMapping("str")
    public String push(String code,String message) {
        log.info("发布applicationEvent事件:{},{}", code, message);
        eventPublisher.publishEvent(new CustomEvent(this, MessageEntity.builder().code(code).message(message).build()));
        return "事件发布成功!";
    }

    @GetMapping("obj")
    public String pushObject(String code,String message) {
        log.info("发布对象事件:{},{}", code, message);
        eventPublisher.publishEvent(MessageEntity.builder().code(code).message(message).build());
        return "对象事件发布成功!";
    }

}
